package com.api.volunteer.interceptor;

import com.api.volunteer.annoation.NoAuth;
import com.api.volunteer.model.Properties;
import com.api.volunteer.model.QUserEntity;
import com.api.volunteer.model.UserEntity;
import com.api.volunteer.util.Holder;
import com.api.volunteer.util.JWTUtil;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.apache.tomcat.util.http.parser.Authorization;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.text.html.Option;
import java.nio.charset.StandardCharsets;
import java.util.Optional;

/**
 * @author 邹宇杰
 * @email 2901570623@qq.com
 * @date 2022/3/30 15:37
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    JPAQueryFactory queryFactory;

    @Autowired
    Holder holder;

    @Value("spring.profiles.active")
    private String active;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            if (handlerMethod.getMethod().getAnnotation(NoAuth.class) != null) {
                //当前方法带有NoAuth注解
                return true;
            }else{
                if(Properties.test.getMsg().equals(active)){
                    return true;
                }
                String token = Optional.ofNullable(request.getHeader(JWTUtil.TOKEN_HEADER)).orElseThrow(() -> {
                    return new RuntimeException("没有请求头信息");
                }).replace(JWTUtil.TOKEN_PREFIX, "");
                if(token.isEmpty()){
                    throw new RuntimeException("错误的Authorization头消息");
                }else{
                    //解析Token
                    if(JWTUtil.isExpiration(token)){
                       throw new RuntimeException("token已经过期了");
                    }else{
                        //正确的Token解析到ThreadLocal中
                        String openid = Optional.ofNullable((String) JWTUtil.getTokenBody(token).get("openid")).orElseThrow(() -> {
                            return new RuntimeException("该用户没有注册");
                        });
                        UserEntity userEntity = Optional.ofNullable(queryFactory.selectFrom(QUserEntity.userEntity).where(QUserEntity.userEntity.openid.eq(openid)).fetchFirst())
                                .orElseThrow(() -> {
                                    return new RuntimeException("错误的openid无法找到该用户");
                                });
                        holder.setUser(userEntity);

                        return true;
                    }
                }
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        holder.removeUser();
    }
}
